package net.sashag.nadlandroid;

import org.json.JSONObject;

import android.app.AlertDialog;
import android.app.ProgressDialog;
import android.content.DialogInterface;
import android.content.DialogInterface.OnClickListener;
import android.content.Intent;
import android.telephony.TelephonyManager;
import android.text.InputType;
import android.util.Log;
import android.view.View;
import android.widget.EditText;
import android.widget.LinearLayout;
import android.widget.RadioGroup;
import android.widget.RadioGroup.OnCheckedChangeListener;
import android.widget.Toast;

import com.google.android.apps.analytics.easytracking.TrackedActivity;
import com.googlecode.androidannotations.annotations.AfterViews;
import com.googlecode.androidannotations.annotations.Background;
import com.googlecode.androidannotations.annotations.Click;
import com.googlecode.androidannotations.annotations.EActivity;
import com.googlecode.androidannotations.annotations.UiThread;
import com.googlecode.androidannotations.annotations.ViewById;
import com.parse.LogInCallback;
import com.parse.ParseException;
import com.parse.ParseFacebookUtils;
import com.parse.ParseUser;
import com.parse.PushService;
import com.parse.SignUpCallback;
import com.parse.facebook.Facebook;

@EActivity(R.layout.signup)
public class SignupActivity extends TrackedActivity {

	@ViewById protected EditText edtFullname;
	@ViewById protected EditText edtEmail;
	@ViewById protected EditText edtPassword;
	@ViewById protected EditText edtPhone;
	@ViewById protected RadioGroup grpSignupOrLogin;
	
	private static final int FACEBOOK_AUTH_REQUEST_CODE = 404;
	
	private ProgressDialog waitDialog;
	
	@AfterViews
	protected void initialUiSetup() {
		grpSignupOrLogin.check(R.id.radSignup);
		grpSignupOrLogin.setOnCheckedChangeListener(new OnCheckedChangeListener() {
			public void onCheckedChanged(RadioGroup group, int checkedId) {
				switch (checkedId) {
				case R.id.radLogin:
					edtFullname.setVisibility(View.GONE);
					edtPhone.setVisibility(View.GONE);
					break;
				case R.id.radSignup:
					edtFullname.setVisibility(View.VISIBLE);
					edtPhone.setVisibility(View.VISIBLE);
					edtFullname.requestFocus();
					break;
				default:
					break;
				}
			}
		});
	}

	@Click(R.id.btnRegisterFacebook)
	protected void onRegisterFacebookClicked() {
		waitDialog = new ProgressDialog(SignupActivity.this);
		waitDialog.setTitle("Please Wait");
		waitDialog.setMessage("Finalizing Facebook login - retrieving your information...");
		waitDialog.setProgressStyle(ProgressDialog.STYLE_SPINNER);
		waitDialog.show();
		ParseFacebookUtils.logIn(this, FACEBOOK_AUTH_REQUEST_CODE, new LogInCallback() {
			public void done(ParseUser user, ParseException e) {
				if (user == null) {
					String errorMessage = "User has cancelled the operation, or an unknown error has occurred.";
					if (e != null) {
						errorMessage = "Facebook login failed: " + e.getMessage();
					}
					Toast.makeText(SignupActivity.this, errorMessage, Toast.LENGTH_LONG).show();
					waitDialog.dismiss();
					Log.e("FacebookLogin", errorMessage);
				} else {
					fillFacebookDetails(user);
				}
			}
		});
	}
	
	@Background
	protected void fillFacebookDetails(ParseUser user) {
		Facebook facebook = ParseFacebookUtils.getFacebook();
		String fullname = "New Facebook user";
		try {
			String details = facebook.request("me");
			JSONObject jsonObj = new JSONObject(details);
			String firstName = jsonObj.getString("first_name");
			String lastName = jsonObj.getString("last_name");
			fullname = firstName + " " + lastName;
		} catch (Exception ex) {
			//Unable to retrieve the user name, this is not critical,
			//although it might be worth trying again some other time.
		}
		signupDone(user, fullname);
	}
	
	@Override
	protected void onActivityResult(int requestCode, int resultCode, Intent data) {
		super.onActivityResult(requestCode, resultCode, data);
		if (requestCode == FACEBOOK_AUTH_REQUEST_CODE) {
			ParseFacebookUtils.finishAuthentication(requestCode, resultCode, data);
		}
	}

	@Click(R.id.btnSignup)
	protected void onSignupClicked() {
		String username = edtEmail.getText().toString();
		String password = edtPassword.getText().toString();
		if (username == null || username.trim().length() == 0) {
			Toast.makeText(this, "Username cannot be blank", Toast.LENGTH_LONG).show();
			return;
		}
		if (password == null || password.trim().length() == 0) {
			Toast.makeText(this, "Password cannot be blank", Toast.LENGTH_LONG).show();
			return;
		}
		
		waitDialog = new ProgressDialog(SignupActivity.this);
		waitDialog.setTitle("Please Wait");
		waitDialog.setMessage("Logging in...");
		waitDialog.setProgressStyle(ProgressDialog.STYLE_SPINNER);
		waitDialog.show();
		final ParseUser user = new ParseUser();
		user.setUsername(username);
		user.setPassword(password);
		user.setEmail(username);
		user.put("Phone", edtPhone.getText().toString());
		user.signUpInBackground(new SignUpCallback() {
			public void done(ParseException e) {
				if (e != null) {
					Toast.makeText(
							SignupActivity.this,
							"Invalid username/password combination, connection error, or username is already taken",
							Toast.LENGTH_LONG).show();
					waitDialog.dismiss();
					Log.e("SignupActivity", "Sign up failed: " + e.getMessage());
				} else {
					String fullname = edtFullname.getText().toString();
					signupDone(user, fullname);
				}
			}
		});
	}
	
	@UiThread
	protected void signupDone(ParseUser user, String fullname) {
		user.put("Fullname", fullname);
		Intent result = new Intent();
		result.putExtra("Fullname", fullname);
		setResult(RESULT_OK, result);
		waitDialog.dismiss();
		//If we don't have the user's email, phone # (because of Facebook signup),
		//ask him to provide these details now so we can store them for contacting
		//him later. The user may opt out.
		promptToFillMissingDetailsIfNecessary(user);
	}
	
	private void finishAndReturn(ParseUser user) {
		user.saveEventually();		
		PushService.subscribe(this, user.getObjectId(), MessagesActivity_.class);
		finish();		
	}

	private void promptToFillMissingDetailsIfNecessary(final ParseUser user) {
		final String phone = user.getString("Phone");
		final String email = user.getEmail();
		if (phone == null || phone.length() == 0 || email == null || email.length() == 0) {
			LinearLayout dialogContent = new LinearLayout(this);
			dialogContent.setOrientation(LinearLayout.VERTICAL);
			final EditText edtMissingPhone = new EditText(this);
			final EditText edtMissingEmail = new EditText(this);
			if (phone == null || phone.length() == 0) {
				edtMissingPhone.setInputType(InputType.TYPE_CLASS_PHONE);
				TelephonyManager telManager = (TelephonyManager) getSystemService(TELEPHONY_SERVICE);
				String possiblePhoneNo = telManager.getLine1Number();
				if (possiblePhoneNo == null || possiblePhoneNo.length() == 0) {
					edtMissingPhone.setHint("555-1212");
				} else {
					edtMissingPhone.setText(possiblePhoneNo);
				}
				dialogContent.addView(edtMissingPhone);
			}
			if (email == null || email.length() == 0) {
				edtMissingEmail.setInputType(InputType.TYPE_TEXT_VARIATION_EMAIL_ADDRESS);
				edtMissingEmail.setHint("name@example.com");
				dialogContent.addView(edtMissingEmail);
			}
			new AlertDialog.Builder(this)
				.setTitle("Fill Missing Details")
				.setMessage("Some of your information is missing. If you provide it, it would be easier for other users to contact you if necessary.")
				.setPositiveButton("Submit", new OnClickListener() {
					public void onClick(DialogInterface dialog, int which) {
						if (email == null || email.length() == 0) {
							String newEmail = edtMissingEmail.getText().toString();
							if (newEmail != null && newEmail.length() > 0) {
								user.setEmail(newEmail);
							}
						}
						if (phone == null || phone.length() == 0) {
							String newPhone = edtMissingPhone.getText().toString();
							if (newPhone != null && newPhone.length() > 0) {
								user.put("Phone", newPhone);
							}
						}
						finishAndReturn(user);
					}
				})
				.setNegativeButton("Dismiss", new OnClickListener() {
					public void onClick(DialogInterface dialog, int which) {
						finishAndReturn(user);
					}
				})
				.setView(dialogContent)
				.show();
		} else  {
			finishAndReturn(user);
		}
	}
}
